# -*- coding: cp1252 -*-
from Tkinter import *
import tkFileDialog
from datetime import datetime, date
import threading
import serial
import pickle

from instrumento.instrumento import *
from planilla.planilla import *
from utilidades.teclado_numerico import teclado_numerico
from utilidades.cronometro import *
#~ from gui_tkinter.gui_tkinter import GuiTkinter


root = Tk()

#-----------------------------------------------------------------------
# variables del puerto serie
#-----------------------------------------------------------------------

fin_s = False

#-----------------------------------------------------------------------
# variables de bloques
#-----------------------------------------------------------------------
# lista de las longitudes estandar de los bloques hasta 100mm
long_nom = [0.5, 1, 1.0005, 1.001, 1.002, 1.003, 1.004, 1.005, 1.006, 1.007, 1.008, 1.009, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.1, 1.11, 1.12,
        1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.2, 1.21, 1.22, 1.23, 1.24, 1.25, 1.26, 1.27, 1.28, 1.29, 1.3, 1.31, 1.32, 1.33, 1.34, 1.35, 1.36, 1.37, 1.38, 1.39,
        1.4, 1.41, 1.42, 1.43, 1.44, 1.45, 1.46, 1.47, 1.48, 1.49, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0,
        9.5, 10.0, 10.5, 11.0, 11.5, 12.0, 12.5, 13.0, 13.5, 14.0, 14.5, 15.0, 15.5, 16.0, 16.5, 17.0, 17.5, 18.0, 18.5, 19.0, 19.5, 20.0, 20.5, 21.0, 21.5, 22.0, 22.5,
        23.0, 23.5, 24.0, 24.5, 25.0, 30.0, 40.0, 50.0, 60.0, 70.0, 75.0, 80.0, 90.0, 100.0]

# cada pseudopestaña corresponde a un elemento de la lista 'trabajos'
trabajos = []
# identificacion de la pseudopestaña actual
numero_trabajo = 0
## cada elemento de trabajos tendrá: [bloques, numero_bloque, tabla, lista_v, quitados, los stringVars]
trabajos.append({'bloques':[], 'numero_bloque':None, 'tabla':{}, 'lista_v':['0' for i in range(2*len(long_nom))],
'quitados':{}, 'elegido':False, 'ot_str':'OT Nro.', 'n1_str':'', 'n2_str':'', 'n3_str':'',
'n4_str':'', 'n5_str':'', 'n_ot_str':'', 'laboratorista_str':'', 'laboratorista_o1_str':'',
'laboratorista_o2_str':'', 'id_patron_str':'', 'marca_str':'', 'material_str':'', 'fecha_str':['', '', '']})
# lista de objetos tipo Bloque (un elemento por cada bloque a calibrar)
bloques = trabajos[0]['bloques']
# identificacion del bloque que se está calibrando
numero_bloque = trabajos[0]['numero_bloque']
# diccionario que guarda los datos de bloques des-seleccionados (se recuperan si se des-seleccionó por error)
quitados = trabajos[0]['quitados']

# lista de botones que representan las pseudotabs
botones = []

# diccionario {indice_lista_de_bloques: indice_lista_de_longitudes}
tabla = trabajos[0]['tabla']
# lista con valores de los check button de selección de bloques
lista_v = trabajos[0]['lista_v']

#-----------------------------------------------------------------------
# variables de la ventana
#-----------------------------------------------------------------------

elegido = trabajos[0]['elegido']
# dimensiones del dibujo esquematico de los bloques con los puntos a medir
ancho_can = 200
alto_can = 260
ancho_blo = ancho_can-20
alto_blo = alto_can/2-15
x_blo = 10
y_blo_1 = 10
y_blo_2 = alto_can/2+5
diametro_marca = 30
separacion_marca = 10 + diametro_marca/2
diametro_punto = 20
# fuentes utilizadas
fuente1 = ("Arial", 16, "bold")
fuente2 = ("Arial", 11, "bold")
fuente3 = ("Arial", 32, "bold")

#-----------------------------------------------------------------------
# variables de carpetas y archivos
#-----------------------------------------------------------------------

# opciones de dialogo para abrir o guardar archivos
file_options = {'defaultextension': '.tesa', 'filetypes':[('todos', '.*'), ('comparadora', '.tesa')], 'initialdir':'C:\\', 'initialfile':'.tesa', 'title':'Trabajo TESA'}
import_options = {'defaultextension': '.xls', 'filetypes':[('todos', '.*'), ('planilla', '.xls')], 'initialdir':'C:\\', 'initialfile':'.xls', 'title':'Importar datos de planilla'}





#-----------------------------------------------------------------------
# clases utilizadas
#-----------------------------------------------------------------------

class PseudoTab:
    """ es un boton con un identificador
    su funcion es similar al de las 'pestañas', para cambiar entre diferentes calibraciones
    """
    def __init__(self, frame, index):
        self.btn = Button(frame, text='Trabajo '+str(index+1), command=self.actualizar)
        self.btn.pack(side=LEFT, anchor=W)
        self.index = index
        self.hundir()

    def actualizar(self):
        """ al cambiar de trabajo se actualiza todo
        """
        global numero_trabajo
        actualizar_trabajos(numero_trabajo)
        numero_trabajo = self.index
        self.hundir()
        actualizar_trabajo(self.index)

        if numero_bloque != None:
            instancia = bloques[numero_bloque].get_instancia()
            medidas = bloques[numero_bloque].get_medidas()
            t_max = bloques[numero_bloque].get_t_max()
            t_min = bloques[numero_bloque].get_t_min()
            id_patron = bloques[numero_bloque].get_id_patron()
            adherencia = bloques[numero_bloque].get_adherencia()
            marca = bloques[numero_bloque].get_marca()
            material = bloques[numero_bloque].get_material()
            n_serie = bloques[numero_bloque].get_n_serie()
            programa.set_all_labels(medidas, t_max, t_min, id_patron, adherencia, marca, material, n_serie, instancia)
        else:
            programa.set_all_labels([], 0, 0, '', '', '', '', 'Ingresar', 0)
        programa.set_lista()
        programa.set_checks()

    def cambiar_nombre(self):
        """ cuando se guarda un trabajo, se actualiza el nombre del
        PseudoTab con el OT
        """
        self.btn.config(text=programa.get_ot()+programa.get_n1()+programa.get_n2()+programa.get_n3()+programa.get_n4()+programa.get_n5())

    def hundir(self):
        """ deja hundido el boton del trabajo actual
        """
        for i in botones: i.btn.config(relief=RAISED)
        self.btn.config(relief=RIDGE)

class GuiTkinter:

    def __init__(self, master) :
        """ el programa tiene un menu y cuadros con la siguiente estructura

        · menu
        · cuadro -> scrolbar
            - bloque seleccionado
                - etiqueta -> identificacion del bloque seleccionado
                - mediciones -> medidas del bloque seleccionado
                - datos_del_bloque -> editar los datos del bloque seleccionado
            - canvas -> esquema de bloque indicando el punto a medir
            - cronometro
            - listado
                - bloques a calibrar
                - listado -> lista de medidas de bloques (seleccionables)
        · pseudotabs -> botones para cambiar entre una OT y otra
        · statusbar -> barra de estado de conecci?n de los puertos serie

        el script est? dise?ado para usar solo el mouse (sin teclado)
        por esto se utilizan objetos tipo StringVar para seleccionar strings entre diferentes opciones
        """
        
        self.master = master

        # tipo de orden de trabajo
        self.ot_var = StringVar(master)
        self.ot_var.set('OT Nro ')
        # cinco digitos decimales que forman el numero de orden de trabajo
        self.n1_var = StringVar(master)
        self.n2_var = StringVar(master)
        self.n3_var = StringVar(master)
        self.n4_var = StringVar(master)
        self.n5_var = StringVar(master)
        self.n_ot_var = StringVar(master)
        self.n_ot_var.set('Ingresar')
        # iniciales del laboratorista
        self.laboratorista_var = StringVar(master)
        self.laboratorista_o1_var = StringVar(master)
        self.laboratorista_o2_var = StringVar(master)
        # datos de los bloques patron (identificacion interna)
        self.id_patron_var = StringVar(master)
        self.id_patron_por_bloque_var = StringVar(master)
        # datos del conjunto de bloques incognita(modificable posteriormente para cada bloque)
        self.adherencia_var = StringVar(master)
        self.coef_exp_var = StringVar(master)
        self.coef_exp_por_bloque_var = StringVar(master)
        self.marca_var = StringVar(master)
        self.marca_por_bloque_var = StringVar(master)
        self.material_var = StringVar(master)
        self.material_por_bloque_var = StringVar(master)
        self.n_serie_var = StringVar(master)
        # fecha de ingreso de los bloques
        self.fecha_d_var = StringVar(master)
        self.fecha_d_var.set('1')
        self.fecha_m_var = StringVar(master)
        self.fecha_m_var.set('1')
        self.fecha_a_var = StringVar(master)
        self.fecha_a_var.set('2014')
        
        self.crono_var = StringVar(master)
#~
        elegido = False


        # Frame inicial que contenga todo
	#~ print 'cuadro'
        self.cuadro = Frame(master)
        self.cuadro.pack(fill=BOTH, expand=1)


        # menu
        menu = Menu(master)
        master.config(menu=menu)

        archivo_menu = Menu(menu)
        menu.add_cascade(label="Archivo", menu=archivo_menu)
        #~ archivo_menu.add_command(label="Nuevo trabajo", command=nuevo_trabajo)
        archivo_menu.add_command(label="Abrir", command=abrir)
        archivo_menu.add_command(label="Guardar", command=guardar)
        #~ archivo_menu.add_command(label="Cerrar trabajo", command=cerrar_trabajo)
        archivo_menu.add_separator()
        #~ archivo_menu.add_command(label="Importar", command=importar)
        #~ archivo_menu.add_separator()
        archivo_menu.add_command(label="Salir", command=cerrar)

        editar_menu = Menu(menu)
        menu.add_cascade(label="Editar", menu=editar_menu)
        editar_menu.add_command(label="Datos de bloques", command=self.editar_bloques)
        editar_menu.add_command(label="Bloques duplicados", command=self.duplicar_bloques)

        gen_menu = Menu(menu)
        menu.add_cascade(label="Generar", menu=gen_menu)
        gen_menu.add_command(label="Planilla", command=generar_hoja)

        #---------------------------------------------------------------
        ## contenido de los datos del bloque actual
        #---------------------------------------------------------------

        self.bloque_seleccionado = Frame(self.cuadro, relief=GROOVE, borderwidth=2)
        self.bloque_seleccionado.grid(row=0, column=0, columnspan=2)

        #---------------------------------------------------------------
        self.etiqueta_bloque = Frame(self.bloque_seleccionado)
        self.etiqueta_bloque.grid(row=0, column=0, columnspan=2, padx=5, pady=12, sticky='WE')
        self.indica_bloque = Label(self.etiqueta_bloque, text='Seleccione un bloque', font=fuente1)
        self.indica_bloque.pack(anchor=W, side=LEFT, fill=X)
        self.indica_ot = Label(self.etiqueta_bloque, text='OT Nro: ', font=fuente1)
        self.indica_ot.pack(anchor=E, side=RIGHT)

        #---------------------------------------------------------------
        self.mediciones = Frame(self.bloque_seleccionado, relief=GROOVE, borderwidth=2)
        self.mediciones.grid(row=1, column=0, columnspan=2, padx=5, pady=12)
        
        self.planitud = Frame(self.mediciones, relief=GROOVE, borderwidth=2)
        self.planitud.grid(row=0, column=0, rowspan=2, padx=5, pady=2)

        Label(self.planitud, text='Ciclo', width=5).grid(row=0, column=0)
        Label(self.planitud, text='BP1', width=12).grid(row=1, column=0)
        Label(self.planitud, text='BP2', width=12).grid(row=2, column=0)
        Label(self.planitud, text='BP3', width=12).grid(row=3, column=0)
        Label(self.planitud, text='BP4', width=12).grid(row=4, column=0)
        Label(self.planitud, text='BP5', width=12).grid(row=5, column=0)
        Label(self.planitud, text='1', width=5).grid(row=0, column=1)
        Label(self.planitud, text='2', width=5).grid(row=0, column=2)
        Label(self.planitud, text='3', width=5).grid(row=0, column=3)
        
        self.centro = Frame(self.mediciones, relief=GROOVE, borderwidth=2)
        self.centro.grid(row=0, column=1, padx=5, pady=2)
        
        Label(self.centro, text='Ciclo', width=5).grid(row=0, column=0)
        Label(self.centro, text='PRi', width=12).grid(row=1, column=0)
        Label(self.centro, text='BP', width=12).grid(row=2, column=0)
        Label(self.centro, text='PRf', width=12).grid(row=3, column=0)
        Label(self.centro, text='1', width=5).grid(row=0, column=1)
        Label(self.centro, text='2', width=5).grid(row=0, column=2)
        Label(self.centro, text='3', width=5).grid(row=0, column=3)
          # etiquetas que muestran los valores leidos
        self.med_lbl = []
        self.temp_lbl = []
        self.texto = []
        self.texto_t = [StringVar(), StringVar()]
        self.texto_t[0].set('___')
        self.texto_t[1].set('___')

        for i in range(15):
            self.texto.append(StringVar())
            self.texto[i].set('___')
            self.lbl_aux = Button(self.planitud, textvariable=self.texto[i], width=12, relief=GROOVE)
            self.med_lbl.append(self.lbl_aux)
            self.med_lbl[i].grid(row=i%5+1, column=i//5+1)
        for i in range(15, 24):
            self.texto.append(StringVar())
            self.texto[i].set('___')
            self.lbl_aux = Button(self.centro, textvariable=self.texto[i], width=12, relief=GROOVE)
            self.med_lbl.append(self.lbl_aux)
            self.med_lbl[i].grid(row=(i-15)%3+1, column=(i-15)//3+1)
        self.med_lbl[0].config(command=cambiar_medicion0)
        self.med_lbl[1].config(command=cambiar_medicion1)
        self.med_lbl[2].config(command=cambiar_medicion2)
        self.med_lbl[3].config(command=cambiar_medicion3)
        self.med_lbl[4].config(command=cambiar_medicion4)
        self.med_lbl[5].config(command=cambiar_medicion5)
        self.med_lbl[6].config(command=cambiar_medicion6)
        self.med_lbl[7].config(command=cambiar_medicion7)
        self.med_lbl[8].config(command=cambiar_medicion8)
        self.med_lbl[9].config(command=cambiar_medicion9)
        self.med_lbl[10].config(command=cambiar_medicion10)
        self.med_lbl[11].config(command=cambiar_medicion11)
        self.med_lbl[12].config(command=cambiar_medicion12)
        self.med_lbl[13].config(command=cambiar_medicion13)
        self.med_lbl[14].config(command=cambiar_medicion14)
        self.med_lbl[15].config(command=cambiar_medicion15)
        self.med_lbl[16].config(command=cambiar_medicion16)
        self.med_lbl[17].config(command=cambiar_medicion17)
        self.med_lbl[18].config(command=cambiar_medicion18)
        self.med_lbl[19].config(command=cambiar_medicion19)
        self.med_lbl[20].config(command=cambiar_medicion20)
        self.med_lbl[21].config(command=cambiar_medicion21)
        self.med_lbl[22].config(command=cambiar_medicion22)
        self.med_lbl[23].config(command=cambiar_medicion23)

        self.etiqueta_temperatura = Frame(self.mediciones, relief=GROOVE, borderwidth=2)
        self.etiqueta_temperatura.grid(row=1, column=1, padx=5, pady=2, sticky=E)

        self.temp_lbl.append(Label(self.etiqueta_temperatura, text = 'T max:'))
        self.temp_lbl[0].grid(row=0, column=0, sticky=E)
        self.temp_lbl.append(Label(self.etiqueta_temperatura, textvariable=self.texto_t[0], width=12, relief=GROOVE))
        self.temp_lbl[1].grid(row=0, column=1, sticky=W)
        self.temp_lbl.append(Label(self.etiqueta_temperatura, text = 'T min:'))
        self.temp_lbl[2].grid(row=1, column=0, sticky=E)
        self.temp_lbl.append(Label(self.etiqueta_temperatura, textvariable=self.texto_t[1], width=12, relief=GROOVE))
        self.temp_lbl[3].grid(row=1, column=1, sticky=W)
        
        #---------------------------------------------------------------
        self.datos_del_bloque = Frame(self.bloque_seleccionado, relief=GROOVE, borderwidth=2)
        self.datos_del_bloque.grid(row=1, column=2, columnspan=2, padx=5, pady=12)
        
        Label(self.datos_del_bloque, text='Patrón: ').grid(row=0, column=0, sticky=E)
        self.patron_actual = OptionMenu(self.datos_del_bloque, self.id_patron_por_bloque_var, 'LIM1-002', 'LIM1-040', 'LIM1-047', command=self.cambiar_id_patron)
        self.patron_actual.grid(row=0, column=1, sticky=W)
        
        Label(self.datos_del_bloque, text='Marca: ').grid(row=1, column=0, sticky=E)
        self.marca_actual = OptionMenu(self.datos_del_bloque, self.marca_por_bloque_var, 'BORLETTI BRA', 'BROWN & SHARPE', 'CARY', 'CEJ', 'DIGIMESS', 'FEDERAL', 'FOWLER', 'FTC', 'HDT', 'HOMMEL WERKE', 'KOBA', 'MAHR', 'MAHR FEDERAL', 'MATRIX', 'MAUSER', 'MITUTOYO', 'OPUS', 'PM', 'PRAT & WHITNEY', 'SCHERR TUMICO', 'SHARS', 'SOMET', 'STARRET', 'TESA', 'TESA CARY', 'WEBBER STARRET', 'SIN MARCA', command=self.cambiar_marca)
        self.marca_actual.grid(row=1, column=1, sticky=W)

        Label(self.datos_del_bloque, text='Material: ').grid(row=2, column=0, sticky=E)
        self.material_actual = OptionMenu(self.datos_del_bloque, self.material_por_bloque_var, 'Acero', 'Tungsteno', command=self.cambiar_material)
        self.material_actual.grid(row=2, column=1, sticky=W)
        
        #~ Label(self.datos_del_bloque, text='Coef. exp.: ').grid(row=3, column=0, sticky=E)
        #~ self.coef_exp_actual = Button(self.datos_del_bloque, textvariable=self.coef_exp_por_bloque_var, command=self.cambiar_coef_exp)
        #~ self.coef_exp_actual.grid(row=3, column=1, sticky=W) 
        
        Label(self.datos_del_bloque, text='Nº Serie: ').grid(row=4, column=0, sticky=E)
        self.n_serie = Button(self.datos_del_bloque, textvariable=self.n_serie_var, command=self.cambiar_n_serie)
        self.n_serie.grid(row=4, column=1, sticky=W)
        
        Label(self.datos_del_bloque, text='Adherencia: ').grid(row=5, column=0, sticky=E)
        self.adherencia = OptionMenu(self.datos_del_bloque, self.adherencia_var, 'Adhiere', 'No adhiere', command=self.cambiar_adherencia)
        self.adherencia.grid(row=5, column=1, sticky=W)
        
        #---------------------------------------------------------------
        ## contenido de los datos del bloque actual
        #---------------------------------------------------------------

        self.listado = Frame(self.cuadro, relief=GROOVE, borderwidth=2)
        self.listado.grid(row=1, column=0, rowspan=2, sticky=W)

        #---------------------------------------------------------------
        # seleccionar un bloque de los elegidos para tomar las mediciones
        self.bloques_a_calibrar = Frame(self.listado)
        self.bloques_a_calibrar.grid(row=0, column=0, rowspan=2, padx=5, pady=12)

        self.scroll_lista = Scrollbar(self.bloques_a_calibrar, orient=VERTICAL)
        self.lista = Listbox(self.bloques_a_calibrar, height=20)
        self.scroll_lista.config(command=self.lista.yview)
        self.scroll_lista.pack(side=RIGHT, fill=Y)
        self.lista.pack(side=LEFT, fill=Y, expand=1)
        self.lista.bind('<ButtonRelease-1>', ir_a_bloque)

        #---------------------------------------------------------------
        # saltar al proximo bloque o quedarse
        self.bloques_a_calibrar_cb = Frame(self.listado)
        self.bloques_a_calibrar_cb.grid(row=1, column=1, padx=5, pady=12)

        self.salto_auto = StringVar(value=1)
        self.salto_auto_cbtn = Checkbutton(self.bloques_a_calibrar_cb, text='Salto al siguiente', variable=self.salto_auto)
        self.salto_auto_cbtn.pack(side=LEFT)

        #---------------------------------------------------------------
        # seleccion de los bloques que se van a calibrar
        self.listado_longitudes = Frame(self.listado, bg=master.cget('bg'))
        self.listado_longitudes.grid(row=0, column=1, padx=5, pady=12)

        # cuadricula con los checks
        self.chk_btn = []
        self.cb_var = []

        # self.chk_lbl = []
        for i in range(2*len(long_nom)):
            self.cb_var.append(StringVar(value=0))

            if i%2==0:
                self.chk_btn.append(Checkbutton(self.listado_longitudes, text=str(long_nom[i//2]), variable=self.cb_var[i], command=lambda: agregar_bloque(self), bg=master.cget('bg')))
                self.chk_btn[i].grid(row=i//20, column=i%20+1, sticky=W)
            else:
                self.chk_btn.append(None)

        #---------------------------------------------------------------
        # dibujo de los bloques:
        self.cuadro_canvas = Frame(self.cuadro, borderwidth=2)
        self.cuadro_canvas.grid(row=1, column=1, sticky=N)

        self.dibujo = Canvas(self.cuadro_canvas, width=ancho_can, height=alto_can, bg="black")
        self.dibujo.pack()

        self.dibujo.create_rectangle(x_blo, y_blo_1, x_blo + ancho_blo, y_blo_1 + alto_blo, outline='white')
        self.dibujo.create_rectangle(x_blo, y_blo_2, x_blo + ancho_blo, y_blo_2 + alto_blo, outline='white')

        self.dibujo.create_oval(x_blo+ancho_blo/2-diametro_marca/2, y_blo_1+alto_blo/2-diametro_marca/2, x_blo+ancho_blo/2+diametro_marca/2, y_blo_1+alto_blo/2+diametro_marca/2, outline='white')
        self.dibujo.create_oval(x_blo+ancho_blo/2-diametro_marca/2, y_blo_2+alto_blo/2-diametro_marca/2, x_blo+ancho_blo/2+diametro_marca/2, y_blo_2+alto_blo/2+diametro_marca/2, outline='white')
        self.dibujo.create_oval(x_blo+separacion_marca-diametro_marca/2, y_blo_2+separacion_marca-diametro_marca/2, x_blo+separacion_marca+diametro_marca/2, y_blo_2+separacion_marca+diametro_marca/2, outline='white')
        self.dibujo.create_oval(x_blo+separacion_marca-diametro_marca/2, y_blo_2+alto_blo-separacion_marca+diametro_marca/2, x_blo+separacion_marca+diametro_marca/2, y_blo_2+alto_blo-separacion_marca-diametro_marca/2, outline='white')
        self.dibujo.create_oval(x_blo+ancho_blo-separacion_marca+diametro_marca/2, y_blo_2+separacion_marca-diametro_marca/2, x_blo+ancho_blo-separacion_marca-diametro_marca/2, y_blo_2+separacion_marca+diametro_marca/2, outline='white')
        self.dibujo.create_oval(x_blo+ancho_blo-separacion_marca+diametro_marca/2, y_blo_2+alto_blo-separacion_marca+diametro_marca/2, x_blo+ancho_blo-separacion_marca-diametro_marca/2, y_blo_2+alto_blo-separacion_marca-diametro_marca/2, outline='white')

        #---------------------------------------------------------------
        # cronometro
        self.cuadro_cronometro = Frame(self.cuadro, borderwidth=2)
        self.cuadro_cronometro.grid(row=2, column=1, sticky=S)
        
        self.cronometro = Cronometro()
        self.crono_var.set('0:00:00')
        self.muestra_crono = Label(self.cuadro_cronometro, textvariable=self.crono_var, font=fuente3)
        self.muestra_crono.grid(row=0, column=0, columnspan=2)
        
        
        self.boton_crono1 = Button(self.cuadro_cronometro, text='Iniciar', command=self.cronometro.inicio)
        self.boton_crono1.grid(row=1, column=0, sticky=E)
        
        self.boton_crono2 = Button(self.cuadro_cronometro, text='Parar', command=self.cronometro.parada)
        self.boton_crono2.grid(row=1, column=1, sticky=W)

        #---------------------------------------------------------------
        # seleccion de trabajo
        #~ self.pseudotabs = Frame(master, relief=GROOVE, borderwidth=2)
        #~ self.pseudotabs.pack(side=TOP, fill=X, anchor=S, padx=1, pady=1)

        #~ self.cuadro_tabs = Frame(self.pseudotabs)
        #~ self.cuadro_tabs.pack(side=LEFT)


        #---------------------------------------------------------------
        ## barra de estado
        #---------------------------------------------------------------
        self.statusbar = Frame(master, relief=SUNKEN, borderwidth=2)
        self.statusbar.pack(side=BOTTOM, fill=X, anchor=S, padx=1, pady=1)
        self.text_rs232 = StringVar()
        self.text_rs232.set('RS-232: ')
        self.estado_rs232 = Label(self.statusbar, textvariable=self.text_rs232)
        self.estado_rs232.pack(side=LEFT)
        self.text_usb = StringVar()
        self.text_usb.set('      USB: ')
        self.estado_usb = Label(self.statusbar, textvariable=self.text_usb)
        self.estado_usb.pack(side=LEFT)

	#~ print 'estado'

    #-------------------------------------------------------------------
    # setters y getters de los stringvars del GUI (strings)
    #-------------------------------------------------------------------

    def set_ot(self, ot):
        self.ot_var.set(ot)
    def set_n_ot(self, n_ot):
        self.n_ot_var.set(n_ot)
    def set_n1(self, n1):
        self.n1_var.set(n1)
    def set_n2(self, n2):
        self.n2_var.set(n2)
    def set_n3(self, n3):
        self.n3_var.set(n3)
    def set_n4(self, n4):
        self.n4_var.set(n4)
    def set_n5(self, n5):
        self.n5_var.set(n5)
    def set_laboratorista(self, laboratorista):
        self.laboratorista_var.set(laboratorista)
    def set_laboratorista_o1(self, laboratorista_o1):
        self.laboratorista_o1_var.set(laboratorista_o1)
    def set_laboratorista_o2(self, laboratorista_o2):
        self.laboratorista_o2_var.set(laboratorista_o2)
    def set_adherencia(self, adherencia):
        self.adherencia_var.set(adherencia)
    def set_id_patron(self, id_patron):
        self.id_patron_var.set(id_patron)
    def set_id_patron_por_bloque(self, id_patron_por_bloque):
        self.id_patron_por_bloque_var.set(id_patron_por_bloque)
    def set_coef_exp(self, coef_exp):
        self.coef_exp_var.set(coef_exp)
    def set_coef_exp_por_bloque(self, coef_exp_por_bloque):
        self.coef_exp_por_bloque_var.set(coef_exp_por_bloque)
    def set_marca(self, marca):
        self.marca_var.set(marca)
    def set_marca_por_bloque(self, marca_por_bloque):
        self.marca_por_bloque_var.set(marca_por_bloque)
    def set_material(self, material):
        self.material_var.set(material)
    def set_material_por_bloque(self, material_por_bloque):
        self.material_por_bloque_var.set(material_por_bloque)
    def set_n_serie(self, n_serie):
        self.n_serie_var.set(n_serie)
    def set_fecha_d(self, fecha_d):
        self.fecha_d_var.set(fecha_d)
    def set_fecha_m(self, fecha_m):
        self.fecha_m_var.set(fecha_m)
    def set_fecha_a(self, fecha_a):
        self.fecha_a_var.set(fecha_a)

    def get_ot(self):
        return self.ot_var.get()
    def get_n_ot(self):
        return self.n_ot_var.get()
    def get_n1(self):
        return self.n1_var.get()
    def get_n2(self):
        return self.n2_var.get()
    def get_n3(self):
        return self.n3_var.get()
    def get_n4(self):
        return self.n4_var.get()
    def get_n5(self):
        return self.n5_var.get()
    def get_laboratorista(self):
        return self.laboratorista_var.get()
    def get_laboratorista_o1(self):
        return self.laboratorista_o1_var.get()
    def get_laboratorista_o2(self):
        return self.laboratorista_o2_var.get()
    def get_adherencia(self):
        return self.adherencia_var.get()
    def get_id_patron(self):
        return self.id_patron_var.get()
    def get_coef_exp(self):
        return self.coef_exp_var.get()
    def get_coef_exp_por_bloque(self):
        return self.coef_exp_por_bloque_var.get()
    def get_marca(self):
        return self.marca_var.get()
    def get_marca_por_bloque(self, marca_por_bloque):
        return self.marca_por_bloque_var.get()
    def get_material(self):
        return self.material_var.get()
    def get_material_por_bloque(self):
        return self.material_por_bloque_var.get()
    def get_n_serie(self):
        return self.n_serie_var.get()
    def get_fecha_d(self):
        return self.fecha_d_var.get()
    def get_fecha_m(self):
        return self.fecha_m_var.get()
    def get_fecha_a(self):
        return self.fecha_a_var.get()
    def get_cb(self, i):
        return self.cb_var[i].get()

    def hundir_instancia(self, instancia=-1):
        """ hunde el boton corespondiente a la instancia indicada
        deshunde el resto
        """
        #~ print instancia
        for i in range(24):
            self.med_lbl[i].config(relief=GROOVE)
        if (instancia >= 0 and instancia < 24):
            self.med_lbl[instancia].config(relief=SUNKEN)
            
    def set_crono(self):
        tiempo = self.cronometro.cuenta()
        self.crono_var.set(tiempo)
        #~ print tiempo
        

    def set_label(self, medidas, instancia):
        """ actualizacion de las medidas mostradas de un bloque y dibujo
        """
        #~ self.texto[instancia].set(str(round(medidas[instancia],2)))
        self.texto[instancia].set("%0.2f" % medidas[instancia])
        #self.set_canvas(instancia)

    def set_temp(self, t_max, t_min):
        self.texto_t[0].set(str(round(t_max, 2)))
        self.texto_t[1].set(str(round(t_min, 2)))

    def set_all_labels(self, medidas, t_max, t_min, id_patron, adherencia, marca, material, n_serie, instancia):
        """ actualizacion de las medidas y temperaturas mostradas al cambiar de bloque,
        del bloque actual, ot del trabajo y dibujo
        """
        if numero_bloque == None:
            self.indica_bloque.config(text='Seleccione un bloque.')
            self.texto_t[0].set('___')
            self.texto_t[1].set('___')
            self.set_adherencia('')
            self.set_id_patron_por_bloque('')
            self.set_marca_por_bloque('')
            self.set_material_por_bloque('')
            self.set_n_serie('')
            for i in range(24):
                self.texto[i].set('___')
                self.med_lbl[i].config(relief=GROOVE)
        else:
            self.indica_bloque.config(text='BP '+ str(long_nom[tabla[numero_bloque]//2])+' mm')
            for i in range(24):
                try:
                    self.texto[i].set("%0.2f" % float(medidas[i]))
                except:
                    self.texto[i].set(medidas[i])
            self.hundir_instancia(instancia)
            self.set_id_patron_por_bloque(id_patron)
            self.set_adherencia(adherencia)
            self.set_marca_por_bloque(marca)
            self.set_material_por_bloque(material)
            self.set_n_serie(n_serie)
            if isinstance(t_max, float):
                self.texto_t[0].set("%0.2f" % t_max)
                self.texto_t[1].set("%0.2f" % t_min)
            else:
                self.texto_t[0].set(str(t_max))
                self.texto_t[1].set(str(t_min))
        self.indica_ot.config(text=self.get_ot()+self.get_n_ot())
        self.set_canvas(instancia)

    def set_canvas(self, instancia):
        """ dibujo esquematico de los bloques indicando el punto donde
        se debe tomar la medicion
        """
        # borrar, se tapan todos los puntos con circulos negros
        self.punto_ref = self.dibujo.create_oval(x_blo+ancho_blo/2-diametro_punto/2, y_blo_1+alto_blo/2-diametro_punto/2, x_blo+ancho_blo/2+diametro_punto/2, y_blo_1+alto_blo/2+diametro_punto/2, outline='black', width=3, fill='black')
        self.punto1_cal = self.dibujo.create_oval(x_blo+ancho_blo/2-diametro_punto/2, y_blo_2+alto_blo/2-diametro_punto/2, x_blo+ancho_blo/2+diametro_punto/2, y_blo_2+alto_blo/2+diametro_punto/2, width=3, fill='black')
        self.punto2_cal = self.dibujo.create_oval(x_blo+separacion_marca-diametro_punto/2, y_blo_2+separacion_marca-diametro_punto/2, x_blo+separacion_marca+diametro_punto/2, y_blo_2+separacion_marca+diametro_punto/2, width=3, fill='black')
        self.punto3_cal = self.dibujo.create_oval(x_blo+separacion_marca-diametro_punto/2, y_blo_2+alto_blo-separacion_marca+diametro_punto/2, x_blo+separacion_marca+diametro_punto/2, y_blo_2+alto_blo-separacion_marca-diametro_punto/2, width=3, fill='black')
        self.punto4_cal = self.dibujo.create_oval(x_blo+ancho_blo-separacion_marca+diametro_punto/2, y_blo_2+separacion_marca-diametro_punto/2, x_blo+ancho_blo-separacion_marca-diametro_punto/2, y_blo_2+separacion_marca+diametro_punto/2, width=3, fill='black')
        self.punto5_cal = self.dibujo.create_oval(x_blo+ancho_blo-separacion_marca+diametro_punto/2, y_blo_2+alto_blo-separacion_marca+diametro_punto/2, x_blo+ancho_blo-separacion_marca-diametro_punto/2, y_blo_2+alto_blo-separacion_marca-diametro_punto/2, width=3, fill='black')

        # dibujar, se marca el punto correspondiente a la instancia de medicion
        # 1     5
        #    3
        # 2     4
        if instancia != None:
            if (instancia==15 or instancia==18 or instancia==21): self.punto_ref=self.dibujo.create_oval(x_blo+ancho_blo/2-diametro_punto/2, y_blo_1+alto_blo/2-diametro_punto/2, x_blo+ancho_blo/2+diametro_punto/2, y_blo_1+alto_blo/2+diametro_punto/2, outline='white', width=3, fill='green')
            elif (instancia==16 or instancia==19 or instancia==22): self.dibujo.create_oval(x_blo+ancho_blo/2-diametro_punto/2, y_blo_2+alto_blo/2-diametro_punto/2, x_blo+ancho_blo/2+diametro_punto/2, y_blo_2+alto_blo/2+diametro_punto/2, outline='yellow', width=3, fill='green')
            elif (instancia==17 or instancia==20 or instancia==23): self.punto_ref=self.dibujo.create_oval(x_blo+ancho_blo/2-diametro_punto/2, y_blo_1+alto_blo/2-diametro_punto/2, x_blo+ancho_blo/2+diametro_punto/2, y_blo_1+alto_blo/2+diametro_punto/2, outline='yellow', width=3, fill='green')
            elif (instancia==0 or instancia==5 or instancia==10): self.dibujo.create_oval(x_blo+separacion_marca-diametro_punto/2, y_blo_2+separacion_marca-diametro_punto/2, x_blo+separacion_marca+diametro_punto/2, y_blo_2+separacion_marca+diametro_punto/2, fill='green')
            elif (instancia==1 or instancia==6 or instancia==11): self.dibujo.create_oval(x_blo+separacion_marca-diametro_punto/2, y_blo_2+alto_blo-separacion_marca+diametro_punto/2, x_blo+separacion_marca+diametro_punto/2, y_blo_2+alto_blo-separacion_marca-diametro_punto/2, fill='green')
            elif (instancia==2 or instancia==7 or instancia==12): self.dibujo.create_oval(x_blo+ancho_blo/2-diametro_punto/2, y_blo_2+alto_blo/2-diametro_punto/2, x_blo+ancho_blo/2+diametro_punto/2, y_blo_2+alto_blo/2+diametro_punto/2, fill='green')
            elif (instancia==3 or instancia==8 or instancia==13): self.dibujo.create_oval(x_blo+ancho_blo-separacion_marca+diametro_punto/2, y_blo_2+alto_blo-separacion_marca+diametro_punto/2, x_blo+ancho_blo-separacion_marca-diametro_punto/2, y_blo_2+alto_blo-separacion_marca-diametro_punto/2, fill='green')
            elif (instancia==4 or instancia==9 or instancia==14): self.dibujo.create_oval(x_blo+ancho_blo-separacion_marca+diametro_punto/2, y_blo_2+separacion_marca-diametro_punto/2, x_blo+ancho_blo-separacion_marca-diametro_punto/2, y_blo_2+separacion_marca+diametro_punto/2, fill='green')
            

    def set_lista(self):
        """ actualizacion de la lista de bloques al agregar o quitar bloque,
        abrir trabajo
        """
        dup=''
        self.lista.delete(0, END)
        for b, m in tabla.items():
            if m%2==1: dup=' dup.'
            self.lista.insert(END, "BP " + str(long_nom[m//2]) + ' mm'+dup)

    def set_checks(self):#, tabla):
        """ actualizacion de color indicador de los bloques elegidos
        """
        self.set_color_cb('limpiar')
        for i in range(len(long_nom)):                                  ############################
            self.cb_var[2*i].set('0')                                   # en el programa principal #
                                                                        ############################
        try:
            for i in range(len(long_nom)):                              #############################
                self.cb_var[2*i+1].set('0')                             # en el TopLevel duplicados #
                                                                        #############################
        except:
            pass

        for b, m in tabla.items():
            self.cb_var[m].set('1')
            #~ try:
            if bloques[b].check():
                self.set_color_cb('chartreuse2', m)
            else:
                self.set_color_cb('orange red', m)
                #~ print 'dale!'
            #~ except:
                #~ pass

    def set_color_cb(self, color, *indice):
        if color == 'limpiar':
            for i in range(len(long_nom)):                                   ############################
                self.cb_var[2*i].set('0')                                     # en el programa principal #
                self.chk_btn[2*i].config(background=self.master.cget('bg'))        ############################
            try:
                for i in range(len(long_nom)):                               #############################
                    self.cb_var[2*i+1].set('0')                               # en el TopLevel duplicados #
                    self.chk_btn[2*i+1].config(background=self.master.cget('bg'))  #############################
            except:
                pass
        elif isinstance(indice, int):
            self.chk_btn[indice].config(background=color)
            #~ print 'indice: '+str(indice)
        elif isinstance(indice, tuple):
            self.chk_btn[indice[0]].config(background=color)
            #~ print 'indice tupla: ' + str(indice[0])
        else:
            print indice
            print 'indice no int: ' + str(indice) + '. Algo anda mal.'
            
    def cambiar_adherencia(self, seleccion):
        bloques[numero_bloque].set_adherencia(seleccion)

    def cambiar_id_patron(self, seleccion):
        bloques[numero_bloque].set_id_patron(seleccion)
    
    def cambiar_marca(self, seleccion):
        bloques[numero_bloque].set_marca(seleccion)

    def cambiar_material(self, seleccion):
        bloques[numero_bloque].set_material(seleccion)
        
    def cambiar_n_serie(self):
        valor_anterior = self.get_n_serie()
        valor = teclado_numerico(self.datos_del_bloque, valor_anterior)
        bloques[numero_bloque].set_n_serie(valor)
        self.set_n_serie(valor)
        
    def cambiar_coef_exp(self):
        valor_anterior = self.get_coef_exp_por_bloque()
        valor = teclado_numerico(self.datos_del_bloque, valor_anterior)
        bloques[numero_bloque].set_coef_exp(valor)
        self.set_coef_exp_por_bloque(valor)
        
    def cambiar_n_ot(self):
        valor_anterior = self.get_n_ot()
        valor = teclado_numerico(self.editar, valor_anterior)
        self.set_n_ot(valor)

    def duplicar_bloques(self):
        self.duplicados = Toplevel(self.cuadro)
        self.duplicados.title('Bloques duplicados.')
        for i in range(2*len(long_nom)):
            if i%2==1:
                self.chk_btn[i]=(Checkbutton(self.duplicados, text=str(long_nom[i//2]), variable=self.cb_var[i], command=lambda: agregar_bloque(self), bg=self.master.cget('bg')))
                self.chk_btn[i].grid(row=i//20, column=i%20+1, sticky=W)
        self.set_checks()

    def editar_bloques(self):
                # datos que van a la planilla
        letnum = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3',
        '4', '5', '6', '7', '8', '9']

        self.editar = Toplevel(self.cuadro)
        self.editar.title('Datos de los bloques.')

        self.ot = OptionMenu(self.editar, self.ot_var, 'OT Nro ','SOT Nro ','RUT Nro ')
        self.ot.grid(row=0,column=0, sticky=E)


        #~ self.n5ot = OptionMenu(self.editar, self.n1_var, '', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
        #~ self.n5ot.grid(row=0,column=1)
        #~ self.n4ot = OptionMenu(self.editar, self.n2_var, '', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
        #~ self.n4ot.grid(row=0,column=2)
        #~ self.n3ot = OptionMenu(self.editar, self.n3_var, '', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
        #~ self.n3ot.grid(row=0,column=3)
        #~ self.n2ot = OptionMenu(self.editar, self.n4_var, '', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
        #~ self.n2ot.grid(row=0,column=4)
        #~ self.n1ot = OptionMenu(self.editar, self.n5_var, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
        #~ self.n1ot.grid(row=0,column=5)
        
        self.n_ot = Button(self.editar, textvariable=self.n_ot_var, command=self.cambiar_n_ot)
        self.n_ot.grid(row=0, column=1, columnspan=5, sticky=W)

        self.fecha = Label(self.editar, text='Fecha de ingreso:', font=fuente2)
        self.fecha.grid(row=1,column=0, sticky=E)

        self.dia = OptionMenu(self.editar, self.fecha_d_var, '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31')
        self.dia.grid(row=1,column=1)

        self.mes = OptionMenu(self.editar, self.fecha_m_var, '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12')
        self.mes.grid(row=1,column=2)

        self.anual = OptionMenu(self.editar, self.fecha_a_var, '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030')
        self.anual.grid(row=1,column=3)

        self.lab = Label(self.editar, text='Laboratorista:', font=fuente2)
        self.lab.grid(row=2,column=0, sticky=E)

        self.laboratorista = OptionMenu(self.editar, self.laboratorista_var, 'AG', 'JO', 'JPC', 'Otro')
        self.laboratorista.grid(row=2,column=1, columnspan=2, sticky=W)

        self.lab_o = Label(self.editar, text='Otro:', font=fuente2)
        self.lab_o.grid(row=2,column=3, sticky=E)

        self.laboratorista_o1 = OptionMenu(self.editar, self.laboratorista_o1_var, *letnum)
        self.laboratorista_o1.grid(row=2,column=4, sticky=W)
        self.laboratorista_o2 = OptionMenu(self.editar, self.laboratorista_o2_var, *letnum)
        self.laboratorista_o2.grid(row=2,column=5, sticky=W)
        
        Label(self.editar, text='Patrón utilizado: ', font=fuente2).grid(row=3, column=0, columnspan=3, sticky=E)
        
        self.id_patron = OptionMenu(self.editar, self.id_patron_var, 'LIM1-002', 'LIM1-040', 'LIM1-047')
        self.id_patron.grid(row=3, column=3, columnspan=2, sticky=W)
        
        Label(self.editar, text='Datos de bloques a calibrar:', font=fuente2).grid(row=4, column=0, columnspan=5, sticky=W)
        
        Label(self.editar, text='Marca: ', font=fuente2).grid(row=5, column=0, sticky=E)

        self.marca = OptionMenu(self.editar, self.marca_var, 'BORLETTI BRA', 'BROWN & SHARPE', 'CARY', 'CEJ', 'DIGIMESS', 'FEDERAL', 'FOWLER', 'FTC', 'HDT', 'HOMMEL WERKE', 'KOBA', 'MAHR', 'MAHR FEDERAL', 'MATRIX', 'MAUSER', 'MITUTOYO', 'OPUS', 'PM', 'PRAT & WHITNEY', 'SCHERR TUMICO', 'SHARS', 'SOMET', 'STARRET', 'TESA', 'TESA CARY', 'WEBBER STARRET', 'SIN MARCA')
        self.marca.grid(row=5, column=1, sticky=W)

        self.material_p_l = Label(self.editar, text='Material: ', font=fuente2)
        self.material_p_l.grid(row=5, column=2, sticky=E)

        self.material = OptionMenu(self.editar, self.material_var, 'Acero', 'Tungsteno')
        self.material.grid(row=5, column=3, sticky=W)

        self.editar.protocol("WM_DELETE_WINDOW", self.fin_editar)

    def fin_editar(self):
        """
        cierra el Toplevel y lleva a cabo los cambios
        """
        self.editar.destroy()
        for b in bloques:
            if b.get_id_patron()=='': b.set_id_patron(self.get_id_patron())
            if b.get_marca()=='': b.set_marca(self.get_marca())
            if b.get_material()=='': b.set_material(self.get_material())
            
        if numero_bloque != None:
            instancia = bloques[numero_bloque].get_instancia()
            medidas = bloques[numero_bloque].get_medidas()
            t_max = bloques[numero_bloque].get_t_max()
            t_min = bloques[numero_bloque].get_t_min()
            id_patron = bloques[numero_bloque].get_id_patron()
            adherencia = bloques[numero_bloque].get_adherencia()
            marca = bloques[numero_bloque].get_marca()
            material = bloques[numero_bloque].get_material()
            n_serie = bloques[numero_bloque].get_n_serie()
            programa.set_all_labels(medidas, t_max, t_min, id_patron, adherencia, marca, material, n_serie, instancia)
        self.indica_ot.config(text=self.get_ot()+self.get_n_ot())


class Bloque:
    def __init__(self, gui):
        """ cada bloque es una lista de medidas mas una variable que
        contiene el indice de la lista, fecha y hora de clibracion,
        temperatura maxima y minima durante la calibracion, material
        """
        self.fecha = str()
        self.hora = str()
        self.instancia = 0
        self.instancia_validacion = 0
        self.medidas = []
        for i in range(24):
            self.medidas.append('...')
        self.t_dif = float()
        self.t_max = '...'
        self.t_min = '...'
        # datos del patron
        self.id_patron = gui.get_id_patron()
        # datos del incognita
        self.adherencia = ''
        self.coef_exp = ''
        self.marca = gui.get_marca()
        self.material = gui.get_material()
        self.n_serie = 'Ingresar'
        
    def __str__(self):
        """ util para debuguear, no se utiliza en el programa
        """
        s  = "medidas tomadas: " + str(self.medidas)
        s += "\ninstancia de medicion actual: cilo " + str(self.instancia//8+1) + ", medida " + str(self.instancia%8+1)
        return s

    def set_adherencia(self, adherencia):
        self.adherencia = adherencia
    def set_coef_exp(self, coef_exp):
        self.coef_exp = coef_exp
    def set_id_patron(self, id_patron):
        self.id_patron = id_patron
    def set_instancia(self, valor):
        """ elegir la instancia de medicion para el bloque actual
        haciendo click sobre el boton que indica la medida
        """
        self.instancia = valor
    def set_instancia_validacion(self, instancia_validacion):
        self.instancia_validacion = instancia_validacion
    def set_marca(self, marca):
        self.marca = marca
    def set_material(self, material):
        self.material = material
    def set_n_serie(self, n_serie):
        self.n_serie = n_serie
    def set_t_max(self, t):
        self.t_max = t
    def set_t_min(self, t):
        self.t_min = t
    
    def set_valor(self, valor):
        """ asignar valor para una medicion determinada
        """
        if self.instancia==0 and isinstance(self.medidas[self.instancia], str):
            fecha = datetime.now()
            self.fecha = datetime.date(fecha)
            self.hora = datetime.time(fecha)
        self.medidas[self.instancia] = valor

    def get_adherencia(self):
        return self.adherencia
    def get_coef_exp(self):
        return self.coef_exp
    def get_fecha(self):
        return self.fecha
    def get_hora(self):
        return self.hora
    def get_id_patron(self):
        return self.id_patron
    def get_instancia(self):
        return self.instancia
    def get_instancia_validacion(self):
        return self.instancia_validacion
    def get_marca(self):
        return self.marca
    def get_material(self):
        return self.material
    def get_medidas(self):
        return self.medidas
    def get_n_serie(self):
        return self.n_serie
    def get_t_max(self):
        return self.t_max
    def get_t_min(self):
        return self.t_min

    def check(self):
        """ determina si a un bloque le faltan datos de medicion
        devuelve verdadero si todas las medidas son tipo float
        """
        var = True
        for i in range(24):
            var = var and isinstance(self.medidas[i], float)
        return var






#-----------------------------------------------------------------------
# funciones
#-----------------------------------------------------------------------

def agregar_bloque(gui):
    """ seleccion de los bloques que se van a calibrar (agragar o quitar)

    en cada seleccion o des-seleccion de un bloque se resetea 'tabla'
    el diccionario tiene como palabra clave el indice de la lista de bloques
    y como valor el indice de la lista de longitudes estandar de bloques
    """
    global lista_v
    global tabla
    global numero_bloque
    global elegido
    j = 0
    k = 0
    tabla = {}
    # si se agrega un bloque nuevo la funci?n devuelve el indice de la lista de bloques
    ret = False
    dup=''
    for i in range(2*len(long_nom)):
        # como se contempla tanto el agregado como el quitado se observa cu?les bloques est?n seleccionados y cu?les lo estaban antes de la ultima modificacion (lista_v)
        if programa.get_cb(i) or lista_v[i]:
            # agregado
            if programa.get_cb(i)=='1':
                # se actualiza 'tabla' con cada bloque que est? seleccionado con los check buttons
                tabla[j] = i
                if lista_v[i]=='0':
                    # aquí se reconoce el bloque agregado
                    # si fue quitado anteriormente se recupera, sino se crea un nuevo objeto tipo Bloque
                    if i in quitados:
                        bloques.insert(j, quitados[i])
                    else:
                        bloques.insert(j, Bloque(gui))
                        bl_insertado = j
                        ret = True
                    if numero_bloque >= j and len(bloques) > 1:
                        # se actualiza el indice del bloque actual
                        numero_bloque += 1
                    # se actualiza la lista de bloques indicando si es o no un bloque duplicado
                    if i%2==1: dup=' dup.'
                    programa.lista.insert(j, "BP " + str(long_nom[i//2]) + ' mm'+dup)
                    # se actualiza el color de fondo del check button
                    if bloques[j].check():
                        programa.chk_btn[i].config(background='chartreuse2')
                    else:
                        programa.chk_btn[i].config(background='orange red')
                j += 1
            # sacar (si no está seleccionado pero lo estaba antes)
            if lista_v[i]=='1':
                if programa.get_cb(i)=='0':
                    # aquí se reconoce el bloque quitado
                    quitados[i] = bloques.pop(k)
                    # se actualiza el indice del bloque actual
                    if numero_bloque > k:
                        numero_bloque -= 1
                    elif numero_bloque == k:
                        numero_bloque = None
                        elegido = False
                    # se actualiza la lista de bloques
                    programa.lista.delete(k)
                    # se actualiza el color de fondo del check button
                    programa.chk_btn[i].config(background=root.cget('bg'))
                k += 1
    # se renueva la lista vieja 'lista_v'
    for k in range(2*len(long_nom)):
        lista_v[k] = programa.get_cb(k)
    if elegido:
        instancia = bloques[numero_bloque].get_instancia()
        medidas = bloques[numero_bloque].get_medidas()
        t_max = bloques[numero_bloque].get_t_max()
        t_min = bloques[numero_bloque].get_t_min()
        id_patron = bloques[numero_bloque].get_id_patron()
        adherencia = bloques[numero_bloque].get_adherencia()
        marca = bloques[numero_bloque].get_marca()
        material = bloques[numero_bloque].get_material()
        n_serie = bloques[numero_bloque].get_n_serie()
        programa.set_all_labels(medidas, t_max, t_min, id_patron, adherencia, marca, material, n_serie, instancia)
    else:
        programa.set_all_labels([], 0, 0, '', '', '', '', 'Ingresar', 0)
    if ret:
        return bl_insertado


def ir_a_bloque(evento):
    """ selccionar un bloque de la lista
    actualiza los datos que se muestran
    """
    global numero_bloque
    global elegido
    elegido= True
    #~ if numero_bloque != None:
        #~ if material_por_bloque_var.get() == '':
            #~ bloques[numero_bloque].material = material_var.get()
        #~ else:
            #~ bloques[numero_bloque].material = material_por_bloque_var.get()
    if evento=='auto':
        numero_bloque += 1
    else:
        numero_bloque = int(programa.lista.curselection()[0])
    programa.set_material_por_bloque(bloques[numero_bloque].get_material)
    instancia = bloques[numero_bloque].get_instancia()
    medidas = bloques[numero_bloque].get_medidas()
    t_max = bloques[numero_bloque].get_t_max()
    t_min = bloques[numero_bloque].get_t_min()
    id_patron = bloques[numero_bloque].get_id_patron()
    adherencia = bloques[numero_bloque].get_adherencia()
    marca = bloques[numero_bloque].get_marca()
    material = bloques[numero_bloque].get_material()
    n_serie = bloques[numero_bloque].get_n_serie()
    programa.set_all_labels(medidas, t_max, t_min, id_patron, adherencia, marca, material, n_serie, instancia)


def medicion_tesa(distancia):
    """ toma el dato de la medicion realizada y modifica el bloque actual
    actualiza valores m?ximo y m?nimo de temperatura
    ?como llegue hasta aca?
     1 abrir_puertos(puertos_disponibles, True)

     2 intenta cerrar las conecciones
     3 abre los puertos
     4 inicia "lectura: leer()"

     5 lee tesa
     6 lee testo
     7 medicion(distancia, temp)
    """
    global numero_bloque
    bloques[numero_bloque].set_valor(distancia)
    instancia = bloques[numero_bloque].get_instancia()
    medidas = bloques[numero_bloque].get_medidas()
    if instancia < 24:
        if (instancia==17 or instancia==20 or instancia==23): # verificación de repetibilidad en el centro
            if abs(medidas[instancia - 2] - distancia) > 0.01:
                bloques[numero_bloque].set_instancia(instancia - 2)
                programa.hundir_instancia(instancia - 2)
                programa.set_canvas(15)
            else:
                bloques[numero_bloque].set_valor(distancia)
                bloques[numero_bloque].set_instancia(instancia + 1)
                programa.hundir_instancia(instancia + 1)
                programa.set_canvas(instancia + 1)
                programa.set_label(bloques[numero_bloque].get_medidas(),
                instancia)
        elif (instancia==4 or instancia==9 or instancia==14): # verificacion de repetibilidad en planitud
            if bloques[numero_bloque].get_instancia_validacion() == 0:
                bloques[numero_bloque].set_instancia_validacion(instancia)
                bloques[numero_bloque].set_valor(distancia)
                programa.hundir_instancia()
                programa.set_canvas(0)
                programa.set_label(bloques[numero_bloque].get_medidas(),
                instancia)
            else:
                if abs(medidas[instancia - 4] - distancia) > 0.02:
                    bloques[numero_bloque].set_instancia(instancia - 4)
                    programa.hundir_instancia(instancia - 4)
                    programa.set_canvas(instancia - 4)
                else:
                    bloques[numero_bloque].set_instancia(instancia + 1)
                    programa.hundir_instancia(instancia + 1)
                    programa.set_canvas(instancia + 1)
                bloques[numero_bloque].set_instancia_validacion(0)
        else:
            bloques[numero_bloque].set_valor(distancia)
            bloques[numero_bloque].set_instancia(instancia + 1)
            programa.hundir_instancia(instancia + 1)
            programa.set_canvas(instancia + 1)
            programa.set_label(bloques[numero_bloque].get_medidas(),
            instancia)
    if instancia==24 and bloques[numero_bloque].check():
        programa.chk_btn[tabla[numero_bloque]].config(background='chartreuse2')
        bloques[numero_bloque].t_dif = temperatura(temp)
        if programa.salto_auto.get() == 1:
            print programa.salto_auto.get()
            ir_a_bloque('auto')
            programa.set_canvas(bloques[numero_bloque].get_instancia())


def temperatura(data):
    """ actualiza t max y min del bloque actual
    """
    t_max = bloques[numero_bloque].get_t_max()
    t_min = bloques[numero_bloque].get_t_min()
    if bloques[numero_bloque].get_instancia() == 1:
        bloques[numero_bloque].set_t_max(data)
        bloques[numero_bloque].set_t_min(data)
    else:
        bloques[numero_bloque].set_t_max(max(t_max, data))
        bloques[numero_bloque].set_t_min(min(t_min, data))
    t_max = bloques[numero_bloque].get_t_max()
    t_min = bloques[numero_bloque].get_t_min()
    return round(t_max - t_min, 2)


def guardar():
    """ guardar los datos del trabajo actual
    """
    destino = tkFileDialog.asksaveasfilename(**file_options)
    if destino:
        if destino[-6:]=='/.tesa':
            if programa.get_n_ot()=='':
                d_h = datetime.now()
                destino = destino[:-5]+str(d_h)[0:10]+'_'+str(d_h)[11:13]+'-'+str(d_h)[14:16]+'-'+str(d_h)[17:19]+destino[-5:]
            else:
                destino =  destino[:-5]+programa.get_ot()+programa.get_n_ot()+destino[-5:]
                botones[numero_trabajo].cambiar_nombre()
        archivo = open(destino, 'wb')
        actualizar_trabajos()

        pickle.dump(trabajos[numero_trabajo], archivo, 2)
        archivo.close()


def abrir():
    """ carga los datos de un trabajo realizado en una nueva 'pseudopestaña'
    """
    global trabajos
    global numero_trabajo

    #~ print numero_bloque

    origen = tkFileDialog.askopenfilename(**file_options)
    if origen:
        archivo = open(origen, 'rb')
        data = pickle.load(archivo)
        archivo.close()
        
        trabajos[numero_trabajo]=data

        """
        # para el uso de múltiples trabajos:
        if (bloques == [] and quitados == {}):
            trabajos[numero_trabajo]=data
        else:
            actualizar_trabajos(numero_trabajo)
            numero_trabajo = len(trabajos)
            trabajos.append(data)
            botones.append(PseudoTab(programa.cuadro_tabs, numero_trabajo))
        """

        actualizar_trabajo(numero_trabajo)
        botones[numero_trabajo].cambiar_nombre()

        #~ print numero_bloque
        if numero_bloque != None:
            instancia = bloques[numero_bloque].get_instancia()
            medidas = bloques[numero_bloque].get_medidas()
            t_max = bloques[numero_bloque].get_t_max()
            t_min = bloques[numero_bloque].get_t_min()
            id_patron = bloques[numero_bloque].get_id_patron()
            adherencia = bloques[numero_bloque].get_adherencia()
            marca = bloques[numero_bloque].get_marca()
            material = bloques[numero_bloque].get_material()
            n_serie = bloques[numero_bloque].get_n_serie()
            programa.set_all_labels(medidas, t_max, t_min, id_patron, adherencia, marca, material, n_serie, instancia)
        else:
            programa.set_all_labels([], 0, 0, '', '', '', '', 'Ingresar', 0)
        programa.set_lista()
        programa.set_checks()


def actualizar_strings(l_numero_trabajo = numero_trabajo):
    """ esta funcion actualiza el contenido de 'trabajos[numero_trabajo]'
    con los valores de los objetos tipo StringVar
    se llama en las funciones: actualizar_trabajos,
    """
    trabajos[l_numero_trabajo]['ot_str'] = programa.get_ot()
    trabajos[l_numero_trabajo]['n_ot_str'] = programa.get_n_ot()
    trabajos[l_numero_trabajo]['n1_str'] = programa.get_n1()
    trabajos[l_numero_trabajo]['n2_str'] = programa.get_n2()
    trabajos[l_numero_trabajo]['n3_str'] = programa.get_n3()
    trabajos[l_numero_trabajo]['n4_str'] = programa.get_n4()
    trabajos[l_numero_trabajo]['n5_str'] = programa.get_n5()
    trabajos[l_numero_trabajo]['laboratorista_str'] = programa.get_laboratorista()
    trabajos[l_numero_trabajo]['laboratorista_o1_str'] = programa.get_laboratorista_o1()
    trabajos[l_numero_trabajo]['laboratorista_o2_str'] = programa.get_laboratorista_o2()
    trabajos[l_numero_trabajo]['id_patron_str'] = programa.get_id_patron()
    trabajos[l_numero_trabajo]['marca_str'] = programa.get_marca()
    trabajos[l_numero_trabajo]['material_str'] = programa.get_material()
    trabajos[l_numero_trabajo]['fecha_str'] = [programa.get_fecha_d(), programa.get_fecha_m(), programa.get_fecha_a()]


def actualizar_stringvars(_numero_trabajo = numero_trabajo):
    """ actualiza el valor de los objetos tipos StringVar 'almacenados' en trabajos[numero_trabajo]
    se llama en las funciones: actualizar_trabajo,
    """
    programa.set_ot(trabajos[_numero_trabajo]['ot_str'])
    programa.set_n_ot(trabajos[_numero_trabajo]['n_ot_str'])
    programa.set_n1(trabajos[_numero_trabajo]['n1_str'])
    programa.set_n2(trabajos[_numero_trabajo]['n2_str'])
    programa.set_n3(trabajos[_numero_trabajo]['n3_str'])
    programa.set_n4(trabajos[_numero_trabajo]['n4_str'])
    programa.set_n5(trabajos[_numero_trabajo]['n5_str'])
    programa.set_laboratorista(trabajos[_numero_trabajo]['laboratorista_str'])
    programa.set_laboratorista_o1(trabajos[_numero_trabajo]['laboratorista_o1_str'])
    programa.set_laboratorista_o2(trabajos[_numero_trabajo]['laboratorista_o2_str'])
    try:
        programa.set_id_patron(trabajos[_numero_trabajo]['id_patron_str'])
        programa.set_marca(trabajos[_numero_trabajo]['marca_str'])
    except:
        pass
    programa.set_material(trabajos[_numero_trabajo]['material_str'])
    programa.set_fecha_d(trabajos[_numero_trabajo]['fecha_str'][0])
    programa.set_fecha_m(trabajos[_numero_trabajo]['fecha_str'][1])
    programa.set_fecha_a(trabajos[_numero_trabajo]['fecha_str'][2])

def actualizar_trabajo(_numero_trabajo=numero_trabajo):
    """ actualiza todas las variables para un trabajo
    variables <--- trabajos[numero_trabajo]
    se llama desde las funciones: abrir, cerrar_trabajo,
    """
    global tabla
    global bloques
    global numero_bloque
    global quitados
    global lista_v

    tabla = trabajos[_numero_trabajo]['tabla']
    bloques = trabajos[_numero_trabajo]['bloques']
    numero_bloque = trabajos[_numero_trabajo]['numero_bloque']
    quitados = trabajos[_numero_trabajo]['quitados']
    lista_v = trabajos[_numero_trabajo]['lista_v']
    actualizar_stringvars(_numero_trabajo)

def actualizar_trabajos(l_numero_trabajo=numero_trabajo):
    """ actualiza el contenido de trabajos[numero_trabajo]
    trabajos[numero_trabajo] <--- variables
    se llama desde las funciones: guardar, PseudoTab.actualizar
    """
    global trabajos

    if numero_bloque != None:                                           ###########################
        if programa.get_material_por_bloque() == '':                           # actualiza el material   #
            bloques[numero_bloque].material = programa.get_material()   # del bloque seleccionado #
        else:                                                           # antes de hacer cambios  #
            bloques[numero_bloque].material = programa.get_material_por_bloque()##########################

    trabajos[l_numero_trabajo]['tabla'] = tabla
    trabajos[l_numero_trabajo]['bloques'] = bloques
    trabajos[l_numero_trabajo]['numero_bloque'] = numero_bloque
    trabajos[l_numero_trabajo]['quitados'] = quitados
    trabajos[l_numero_trabajo]['lista_v'] = lista_v
    actualizar_strings(l_numero_trabajo)
    #~ print trabajos

def cerrar_trabajo():
    """ elimina el trabajo actual de la lista trabajos y el boton (pseudotab) correspondiente
    """
    global trabajos
    global numero_trabajo
    trabajos.remove(trabajos[numero_trabajo])
    botones[numero_trabajo].btn.pack_forget()
    botones.remove(botones[numero_trabajo])
    if trabajos == []:
        nuevo_trabajo()
    numero_trabajo = 0
    botones[0].hundir()
    for i in range(len(botones)): botones[i].index=i    # se actualizan los indices
    actualizar_trabajo()

    if numero_bloque != None:
        instancia = bloques[numero_bloque].get_instancia()
        medidas = bloques[numero_bloque].get_medidas()
        t_max = bloques[numero_bloque].get_t_max()
        t_min = bloques[numero_bloque].get_t_min()
        id_patron = bloques[numero_bloque].get_id_patron()
        adherencia = bloques[numero_bloque].get_adherencia()
        marca = bloques[numero_bloque].get_marca()
        material = bloques[numero_bloque].get_material()
        n_serie = bloques[numero_bloque].get_n_serie()
        programa.set_all_labels(medidas, t_max, t_min, id_patron, adherencia, marca, material, n_serie, instancia)
    else:
        programa.set_all_labels([], 0, 0, '', '', '', '', 'Ingresar', 0)
    programa.set_lista()
    programa.set_checks()



def nuevo_trabajo():
    """ el trabajo actual no se 'cierra'
    se crea una PseudoTab (boton para cambiar de trabajo)
    se agrega un diccionario en la lista trabajos
    """
    global trabajos
    global numero_trabajo
    if (bloques == [] and quitados == {} and not(trabajos == [])):
        trabajos[numero_trabajo]={'bloques':[], 'numero_bloque':None, 'tabla':{}, 'lista_v':['0' for i in range(2*len(long_nom))],
            'quitados':{}, 'elegido':False, 'ot_str':'OT Nro.', 'n1_str':'', 'n2_str':'', 'n3_str':'',
            'n4_str':'', 'n5_str':'', 'n_ot_str':'', 'laboratorista_str':'', 'laboratorista_o1_str':'',
            'laboratorista_o2_str':'', 'id_patron_str':'', 'marca_str':'', 'material_str':'', 'fecha_str':['', '', '']}
    elif trabajos == []:
        trabajos.append({'bloques':[], 'numero_bloque':None, 'tabla':{}, 'lista_v':['0' for i in range(2*len(long_nom))],
            'quitados':{}, 'elegido':False, 'ot_str':'OT Nro.', 'n1_str':'', 'n2_str':'', 'n3_str':'',
            'n4_str':'', 'n5_str':'', 'n_ot_str':'', 'laboratorista_str':'', 'laboratorista_o1_str':'',
            'laboratorista_o2_str':'', 'id_patron_str':'', 'marca_str':'', 'material_str':'', 'fecha_str':['', '', '']})
        botones.append(PseudoTab(programa.cuadro_tabs, numero_trabajo))
    else:
        actualizar_trabajos(numero_trabajo)
        numero_trabajo = len(trabajos)
        trabajos.append({'bloques':[], 'numero_bloque':None, 'tabla':{}, 'lista_v':['0' for i in range(2*len(long_nom))],
            'quitados':{}, 'elegido':False, 'ot_str':'OT Nro.', 'n1_str':'', 'n2_str':'', 'n3_str':'',
            'n4_str':'', 'n5_str':'', 'n_ot_str':'', 'laboratorista_str':'', 'laboratorista_o1_str':'',
            'laboratorista_o2_str':'', 'id_patron_str':'', 'marca_str':'', 'material_str':'', 'fecha_str':['', '', '']})
        botones.append(PseudoTab(programa.cuadro_tabs, numero_trabajo))
    actualizar_trabajo(numero_trabajo)

    if numero_bloque != None:
        instancia = bloques[numero_bloque].get_instancia()
        medidas = bloques[numero_bloque].get_medidas()
        t_max = bloques[numero_bloque].get_t_max()
        t_min = bloques[numero_bloque].get_t_min()
        id_patron = bloques[numero_bloque].get_id_patron()
        adherencia = bloques[numero_bloque].get_adherencia()
        marca = bloques[numero_bloque].get_marca()
        material = bloques[numero_bloque].get_material()
        n_serie = bloques[numero_bloque].get_n_serie()
        programa.set_all_labels(medidas, t_max, t_min, id_patron, adherencia, marca, material, n_serie, instancia)
    else:
        programa.set_all_labels([], 0, 0, '', '', '', '', 'Ingresar', 0)
    programa.set_lista()
    programa.set_checks()

def hex2cen(hexa): # instrumento-.
    """ funion que recibe el dato que devuelve el termometro y devuelve
    la temperatura en grados centigrados
    la curva que devuelve la temperatura en grados se ajusta con ensayos
    y con los datos de calibracion del aparato
    """
    t_ref = 19.95
    value_ref = 4300703     # 'n0'
    data_f = hexa[-6:]      # 'n' desordenado en hexadecimal
    value_absh = data_f[4:6]+data_f[2:4]+data_f[0:2]    # 'n' en hexadecimal
    print value_absh
    value_abs = int('0x'+value_absh,0)  # 'n'
    print value_abs
    t = t_ref + (value_abs - value_ref)*0.00048940814   # t = t_ref + a*(n - n0)
    return t


def cerrar():
    """ cierra las comunicaciones serie. importante para poder abrirla
     nuevamente con la ejecucion del programa
    """
    fin_s = True
    try:
        s_tesa.close()
    except:
        pass
    try:
        s_testo.close()
    except:
        pass
    root.destroy()

def generar_hoja():
    """ funcion que se llama desde el menu y usa la clase Planilla
    """
    planilla = Planilla(bloques)
    planilla.encabezado(programa.get_ot(), programa.get_n_ot(), 
        programa.get_marca(), 
        programa.get_material(), programa.get_fecha_a(), 
        programa.get_fecha_m(), programa.get_fecha_d(), long_nom,
        tabla, bloques)
    planilla.escribir_medidas(programa.get_laboratorista(),
        programa.get_laboratorista_o1(), programa.get_laboratorista_o2(), 
        long_nom, tabla, bloques)
    planilla.crear_informe(bloques)

    destino = tkFileDialog.asksaveasfilename(defaultextension='.xls',
    filetypes=[('todos', '.*'), ('planilla', '.xls')], initialdir='C:\\',
    initialfile='.xls', title='Exportar trabajo TESA')
    if destino:
        if destino[-5:]=='/.xls':
            if programa.get_n_ot()=='':
                d_h = datetime.now()
                destino = destino[:-5]+str(d_h)[0:10]+'_'+str(d_h)[11:13]+'-'+str(d_h)[14:16]+'-'+str(d_h)[17:19]+destino[-4:]
            else:
                destino =  destino[:-4] + programa.get_ot() + programa.get_n_ot() + destino[-4:]
        planilla.save_sheet(destino)


def importar():
    """ carga datos de mediciones desde una planilla
    *******************************************************
    debido a modificaciones no funciona correctamente
    si es necesario se corregira y optimizara en el futuro
    *******************************************************
    """
    global material_var
    origen = tkFileDialog.askopenfilename(**import_options)
    if origen:
        book = open_workbook(origen, formatting_info=True)
        hoja_med_imp = book.sheet_by_index(1)


        i = 0 # indice de bloque en planilla
        ln = hoja_med_imp.cell(14+i,9).value # longitud nominal del bloque
        while isinstance(ln, float):
            if not(long_nom.index(ln) in tabla.values()):
                programa.cb_var[long_nom.index(ln)].set('1')
                b = agregar_bloque()
                bloques[b].fecha = xldate_as_tuple(hoja_med_imp.cell(21+i,10).value,book.datemode)
                bloques[b].hora = xldate_as_tuple(hoja_med_imp.cell(23+i,10).value,book.datemode)
                bloques[b].t_dif = hoja_med_imp.cell(23+i, 6).value
                print bloques[b].fecha, bloques[b].hora
                for j in range(24):
                    bloques[b].instancia = j
                    if j%8 < 3:
                        bloques[b].set_valor(hoja_med_imp.cell(nrows_i+nrows_c+j%8+1+i,2+j//8).value)
                    else:
                        bloques[b].set_valor(hoja_med_imp.cell(nrows_i+nrows_p+j%8-2+i,2+j//8).value)
            i += nrows_b
            ln = hoja_med_imp.cell(14+i,9).value

        if str(hoja_med_imp.cell(1, 3))[7]=='T':
            material_var.set('Tungsteno')
        else:
            material_var.set('Acero')

        programa.set_checks()


  # cambiar instancia de medicion con click


def cambiar_medicion0():
    bloques[numero_bloque].set_instancia(0)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(0)
    programa.hundir_instancia(0)
def cambiar_medicion1():
    bloques[numero_bloque].set_instancia(1)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(1)
    programa.hundir_instancia(1)
def cambiar_medicion2():
    bloques[numero_bloque].set_instancia(2)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(2)
    programa.hundir_instancia(2)
def cambiar_medicion3():
    bloques[numero_bloque].set_instancia(3)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(3)
    programa.hundir_instancia(3)
def cambiar_medicion4():
    bloques[numero_bloque].set_instancia(4)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(4)
    programa.hundir_instancia(4)
def cambiar_medicion5():
    bloques[numero_bloque].set_instancia(5)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(5)
    programa.hundir_instancia(5)
def cambiar_medicion6():
    bloques[numero_bloque].set_instancia(6)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(6)
    programa.hundir_instancia(6)
def cambiar_medicion7():
    bloques[numero_bloque].set_instancia(7)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(7)
    programa.hundir_instancia(7)
def cambiar_medicion8():
    bloques[numero_bloque].set_instancia(8)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(8)
    programa.hundir_instancia(8)
def cambiar_medicion9():
    bloques[numero_bloque].set_instancia(9)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(9)
    programa.hundir_instancia(9)
def cambiar_medicion10():
    bloques[numero_bloque].set_instancia(10)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(10)
    programa.hundir_instancia(10)
def cambiar_medicion11():
    bloques[numero_bloque].set_instancia(11)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(11)
    programa.hundir_instancia(11)
def cambiar_medicion12():
    bloques[numero_bloque].set_instancia(12)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(12)
    programa.hundir_instancia(12)
def cambiar_medicion13():
    bloques[numero_bloque].set_instancia(13)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(13)
    programa.hundir_instancia(13)
def cambiar_medicion14():
    bloques[numero_bloque].set_instancia(14)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(14)
    programa.hundir_instancia(14)
def cambiar_medicion15():
    bloques[numero_bloque].set_instancia(15)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(15)
    programa.hundir_instancia(15)
def cambiar_medicion16():
    bloques[numero_bloque].set_instancia(16)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(16)
    programa.hundir_instancia(16)
def cambiar_medicion17():
    bloques[numero_bloque].set_instancia(17)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(17)
    programa.hundir_instancia(17)
def cambiar_medicion18():
    bloques[numero_bloque].set_instancia(18)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(18)
    programa.hundir_instancia(18)
def cambiar_medicion19():
    bloques[numero_bloque].set_instancia(19)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(19)
    programa.hundir_instancia(19)
def cambiar_medicion20():
    bloques[numero_bloque].set_instancia(20)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(20)
    programa.hundir_instancia(20)
def cambiar_medicion21():
    bloques[numero_bloque].set_instancia(21)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(21)
    programa.hundir_instancia(21)
def cambiar_medicion22():
    bloques[numero_bloque].set_instancia(22)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(22)
    programa.hundir_instancia(22)
def cambiar_medicion23():
    bloques[numero_bloque].set_instancia(23)
    bloques[numero_bloque].set_instancia_validacion(0)
    programa.set_canvas(23)
    programa.hundir_instancia(23)


def medicion_testo(temp):
    temperatura(temp)
    t_max = bloques[numero_bloque].get_t_max()
    t_min = bloques[numero_bloque].get_t_min()
    programa.set_temp(t_max, t_min)


def leer():
    """ lectura de RS-232 (cuando fin=1 se termina el thread)
    luego de la lectura se solicita la temperatura al termometro
    ?como llegue hasta aca?
     1 abrir_puertos(puertos_disponibles, True)

     2 intenta cerrar las conecciones
     3 abre los puertos
     4 inicia "lectura: leer()"
    """

    while not(fin_s):
        lectura_t = 3
        try:
            data = tesa.leer()
            distancia = float(data)
            print distancia
            medicion_tesa(distancia)
        except:
            print "Excepcion: error tesa..."
        while lectura_t != 0:
            try:
                temp = testo.leer()
                print temp
                medicion_testo(float(temp))
                lectura_t = 0
            except:
                print "Excepcion: error testo..."
                lectura_t -= 1
                print 'intentos restantes: ' + str(lectura_t)

def abrir_puertos(puertos_disponibles, inicial=False):
    """ intenta cerrar las conecciones serie y
    luego los abre (en caso de que los puertos est?n disponibles)
    se llama luego de crear los instrumentos:
    abrir_puertos(puertos_disponibles, True)
    """
    #~ print 'reabre'
    tesa.terminar()
    testo.terminar()
    if len(puertos_disponibles)>1:
        print 'inicia testo'
        puerto_testo = puertos_disponibles[1]
        if inicial:
            testo.set_port(puerto_testo, 1200, 'E', 7, 2)
        testo.iniciar(puerto_testo)
    else:
        pass # informar en la barra de estado

    if len(puertos_disponibles)>0:
        print 'inicia tesa'
        puerto_tesa = puertos_disponibles[0]
        if inicial:
            tesa.set_port(puerto_tesa, 1200, 'E', 7, 2)
        tesa.iniciar(puerto_tesa)
        lectura.start()
    else:
        pass # informar en la barra de estado
        
def set_crono():
    while not(fin_s):
        programa.set_crono()
        time.sleep(0.2)

#-----------------------------------------------------------------------
# iniciar programa principal
#-----------------------------------------------------------------------

root.title('Tesa')
root.geometry("%dx%d%+d%+d" % (950, 660, 0, 0))
root.protocol("WM_DELETE_WINDOW", cerrar)

#~ planilla = Planilla()

programa = GuiTkinter(root)
#~ botones.append(PseudoTab(programa.cuadro_tabs, 0))



programa.med_lbl[0].config(relief=SUNKEN)

  # puerto serie

tesa = Tesa()
testo = Testo()
lectura = threading.Thread(target=leer)
hilo_crono = threading.Thread(target=set_crono)
hilo_crono.setDaemon(True)


puertos_disponibles = Instrumento.scan_ports(30)
print puertos_disponibles










if __name__=='__main__':
    abrir_puertos(puertos_disponibles, True)
    hilo_crono.start()
    root.mainloop()









